<template>
  <div class="file-manager-container">
    <el-card>
      <div slot="header">
        <span>文件管理器</span>
        <el-button style="float: right; padding: 3px 0" type="text" @click="refreshCurrentPath">
          <i class="el-icon-refresh"></i> 刷新
        </el-button>
      </div>
      
      <div v-loading="loading">
        <!-- 路径导航 -->
        <div class="file-path">
          <el-breadcrumb separator="/">
            <el-breadcrumb-item :to="{ path: '/file', query: { path: '/' } }">
              <i class="el-icon-s-home"></i> 根目录
            </el-breadcrumb-item>
            <el-breadcrumb-item v-for="(segment, index) in pathSegments" :key="index" 
                               :to="{ path: '/file', query: { path: getPathUpTo(index) } }">
              {{ segment }}
            </el-breadcrumb-item>
          </el-breadcrumb>
        </div>
        
        <!-- 工具栏 -->
        <div class="file-toolbar">
          <el-button-group>
            <el-button size="small" icon="el-icon-upload" @click="showUploadDialog">上传</el-button>
            <el-button size="small" icon="el-icon-folder-add" @click="showNewFolderDialog">新建文件夹</el-button>
            <el-button size="small" icon="el-icon-document-add" @click="showNewFileDialog">新建文件</el-button>
          </el-button-group>
          
          <el-input placeholder="在当前目录搜索" v-model="searchQuery" prefix-icon="el-icon-search" clearable
                    size="small" style="width: 200px; margin-left: 10px;">
          </el-input>
        </div>
        
        <!-- 文件列表 -->
        <el-table :data="filteredFiles" style="width: 100%" @row-dblclick="handleDblclick">
          <el-table-column width="50">
            <template v-slot="scope">
              <i :class="getFileIcon(scope.row)" style="font-size: 18px;"></i>
            </template>
          </el-table-column>
          
          <el-table-column prop="name" label="名称" sortable>
            <template v-slot="scope">
              <span @click="navigate(scope.row)" class="file-name">{{ scope.row.name }}</span>
            </template>
          </el-table-column>
          
          <el-table-column prop="size" label="大小" sortable width="150" :formatter="formatSize"></el-table-column>
          <el-table-column prop="mtime" label="修改时间" sortable width="180" :formatter="formatDate"></el-table-column>
          <el-table-column prop="permissions" label="权限" width="100"></el-table-column>
          
          <el-table-column label="操作" width="220">
            <template v-slot="scope">
              <el-button size="mini" type="primary" @click="handleEdit(scope.row)" 
                       :disabled="!isEditable(scope.row)">编辑</el-button>
              <el-button size="mini" type="warning" @click="handleRename(scope.row)">重命名</el-button>
              <el-button size="mini" type="danger" @click="handleDelete(scope.row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </el-card>
    
    <!-- 上传文件对话框 -->
    <el-dialog title="上传文件" :visible.sync="uploadDialogVisible" width="400px">
      <el-upload
        class="upload-demo"
        drag
        action="#"
        :http-request="handleUpload"
        multiple>
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">拖拽文件到此处或<em>点击上传</em></div>
        <div class="el-upload__tip" slot="tip">上传的文件将保存到当前目录</div>
      </el-upload>
    </el-dialog>
    
    <!-- 新建文件夹对话框 -->
    <el-dialog title="新建文件夹" :visible.sync="newFolderDialogVisible" width="400px">
      <el-form :model="newFolderForm" label-width="80px">
        <el-form-item label="文件夹名">
          <el-input v-model="newFolderForm.name" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="newFolderDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="createFolder">创建</el-button>
      </div>
    </el-dialog>
    
    <!-- 新建文件对话框 -->
    <el-dialog title="新建文件" :visible.sync="newFileDialogVisible" width="800px">
      <el-form :model="newFileForm" label-width="80px">
        <el-form-item label="文件名">
          <el-input v-model="newFileForm.name" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="内容">
          <div style="height: 400px; border: 1px solid #dcdfe6; border-radius: 4px;">
            <textarea style="width: 100%; height: 100%; border: none; padding: 10px;" v-model="newFileForm.content"></textarea>
          </div>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="newFileDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="createFile">创建</el-button>
      </div>
    </el-dialog>
    
    <!-- 编辑文件对话框 -->
    <el-dialog title="编辑文件" :visible.sync="editFileDialogVisible" width="800px">
      <div v-loading="fileContentLoading">
        <div style="height: 500px; border: 1px solid #dcdfe6; border-radius: 4px;">
          <textarea style="width: 100%; height: 100%; border: none; padding: 10px;" v-model="editFileContent"></textarea>
        </div>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="editFileDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="saveFile">保存</el-button>
      </div>
    </el-dialog>
    
    <!-- 重命名对话框 -->
    <el-dialog title="重命名" :visible.sync="renameDialogVisible" width="400px">
      <el-form :model="renameForm" label-width="80px">
        <el-form-item label="新名称">
          <el-input v-model="renameForm.newName" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="renameDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="renameItem">确认</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'

// 模拟文件数据
const mockFiles = {
  '/': [
    { name: 'home', type: 'directory', size: 0, mtime: new Date(), permissions: 'drwxr-xr-x' },
    { name: 'etc', type: 'directory', size: 0, mtime: new Date(), permissions: 'drwxr-xr-x' },
    { name: 'var', type: 'directory', size: 0, mtime: new Date(), permissions: 'drwxr-xr-x' },
    { name: 'usr', type: 'directory', size: 0, mtime: new Date(), permissions: 'drwxr-xr-x' },
  ],
  '/home': [
    { name: 'user', type: 'directory', size: 0, mtime: new Date(), permissions: 'drwxr-xr-x' },
    { name: '.bash_profile', type: 'file', size: 1024, mtime: new Date(), permissions: '-rw-r--r--' },
  ],
  '/etc': [
    { name: 'nginx', type: 'directory', size: 0, mtime: new Date(), permissions: 'drwxr-xr-x' },
    { name: 'mysql', type: 'directory', size: 0, mtime: new Date(), permissions: 'drwxr-xr-x' },
    { name: 'hosts', type: 'file', size: 2048, mtime: new Date(), permissions: '-rw-r--r--' },
    { name: 'resolv.conf', type: 'file', size: 512, mtime: new Date(), permissions: '-rw-r--r--' },
  ],
  '/etc/nginx': [
    { name: 'nginx.conf', type: 'file', size: 4096, mtime: new Date(), permissions: '-rw-r--r--' },
    { name: 'conf.d', type: 'directory', size: 0, mtime: new Date(), permissions: 'drwxr-xr-x' },
  ],
  '/var': [
    { name: 'log', type: 'directory', size: 0, mtime: new Date(), permissions: 'drwxr-xr-x' },
    { name: 'www', type: 'directory', size: 0, mtime: new Date(), permissions: 'drwxr-xr-x' },
  ],
  '/var/log': [
    { name: 'nginx', type: 'directory', size: 0, mtime: new Date(), permissions: 'drwxr-xr-x' },
    { name: 'syslog', type: 'file', size: 102400, mtime: new Date(), permissions: '-rw-r--r--' },
  ]
}

// 模拟文件内容
const mockFileContents = {
  '/etc/hosts': '127.0.0.1 localhost\n::1 localhost ip6-localhost ip6-loopback',
  '/etc/resolv.conf': 'nameserver 8.8.8.8\nnameserver 8.8.4.4',
  '/etc/nginx/nginx.conf': 'user nginx;\nworker_processes auto;\n\nevents {\n    worker_connections 1024;\n}\n\nhttp {\n    include /etc/nginx/conf.d/*.conf;\n}'
}

export default {
  name: 'FileManager',
  data() {
    return {
      loading: false,
      files: [],
      currentPath: '/',
      searchQuery: '',
      
      uploadDialogVisible: false,
      newFolderDialogVisible: false,
      newFileDialogVisible: false,
      editFileDialogVisible: false,
      renameDialogVisible: false,
      
      newFolderForm: {
        name: ''
      },
      newFileForm: {
        name: '',
        content: ''
      },
      editFileContent: '',
      fileContentLoading: false,
      currentEditFile: null,
      
      renameForm: {
        newName: ''
      },
      currentRenameItem: null,
      
      useMockData: true // 使用模拟数据
    }
  },
  computed: {
    ...mapGetters([
      'isAdmin'
    ]),
    
    // 路径分段
    pathSegments() {
      if (this.currentPath === '/') return []
      return this.currentPath.split('/').filter(segment => segment)
    },
    
    // 根据搜索查询过滤文件
    filteredFiles() {
      if (!this.searchQuery) return this.files
      
      return this.files.filter(file => 
        file.name.toLowerCase().includes(this.searchQuery.toLowerCase())
      )
    }
  },
  created() {
    this.currentPath = this.$route.query.path || '/'
    this.fetchFiles()
  },
  watch: {
    '$route.query.path': {
      handler(newPath) {
        this.currentPath = newPath || '/'
        this.fetchFiles()
      }
    }
  },
  methods: {
    // 获取指定路径下的文件列表
    fetchFiles() {
      this.loading = true
      
      if (this.useMockData) {
        // 使用模拟数据
        setTimeout(() => {
          this.files = mockFiles[this.currentPath] || []
          this.loading = false
        }, 500)
      } else {
        // 实际API调用
        this.$http.get('/file/list', { params: { path: this.currentPath } })
          .then(res => {
            this.files = res.data
            this.loading = false
          })
          .catch(error => {
            this.$message.error(error.response?.data?.error || '获取文件列表失败')
            this.loading = false
            
            // 如果API调用失败，切换到模拟数据
            if (!this.useMockData) {
              this.useMockData = true
              this.fetchFiles()
            }
          })
      }
    },
    
    // 刷新当前路径
    refreshCurrentPath() {
      this.fetchFiles()
    },
    
    // 导航到文件夹或查看/编辑文件
    navigate(file) {
      if (file.type === 'directory') {
        const path = this.currentPath === '/' ? `/${file.name}` : `${this.currentPath}/${file.name}`
        this.$router.push({ path: '/file', query: { path } })
      } else {
        this.handleEdit(file)
      }
    },
    
    // 双击处理
    handleDblclick(row) {
      this.navigate(row)
    },
    
    // 显示上传对话框
    showUploadDialog() {
      if (!this.isAdmin) {
        this.$message.warning('需要管理员权限进行此操作')
        return
      }
      this.uploadDialogVisible = true
    },
    
    // 处理文件上传
    handleUpload(options) {
      if (this.useMockData) {
        setTimeout(() => {
          this.$message.success(`${options.file.name} 上传成功`)
          this.uploadDialogVisible = false
          
          // 添加到当前文件列表
          this.files.push({
            name: options.file.name,
            type: 'file',
            size: options.file.size,
            mtime: new Date(),
            permissions: '-rw-r--r--'
          })
        }, 1000)
      } else {
        const formData = new FormData()
        formData.append('file', options.file)
        formData.append('path', this.currentPath)
        
        this.$http.post('/file/upload', formData)
          .then(() => {
            this.$message.success(`${options.file.name} 上传成功`)
            this.uploadDialogVisible = false
            this.fetchFiles()
          })
          .catch(error => {
            this.$message.error(error.response?.data?.error || '上传失败')
          })
      }
    },
    
    // 显示新建文件夹对话框
    showNewFolderDialog() {
      if (!this.isAdmin) {
        this.$message.warning('需要管理员权限进行此操作')
        return
      }
      this.newFolderForm.name = ''
      this.newFolderDialogVisible = true
    },
    
    // 创建文件夹
    createFolder() {
      if (!this.newFolderForm.name) {
        this.$message.warning('文件夹名不能为空')
        return
      }
      
      if (this.useMockData) {
        setTimeout(() => {
          // 添加到当前文件列表
          this.files.push({
            name: this.newFolderForm.name,
            type: 'directory',
            size: 0,
            mtime: new Date(),
            permissions: 'drwxr-xr-x'
          })
          
          this.$message.success('文件夹创建成功')
          this.newFolderDialogVisible = false
        }, 500)
      } else {
        this.$http.post('/file/mkdir', {
          path: this.currentPath,
          name: this.newFolderForm.name
        })
          .then(() => {
            this.$message.success('文件夹创建成功')
            this.newFolderDialogVisible = false
            this.fetchFiles()
          })
          .catch(error => {
            this.$message.error(error.response?.data?.error || '创建文件夹失败')
          })
      }
    },
    
    // 显示新建文件对话框
    showNewFileDialog() {
      if (!this.isAdmin) {
        this.$message.warning('需要管理员权限进行此操作')
        return
      }
      this.newFileForm.name = ''
      this.newFileForm.content = ''
      this.newFileDialogVisible = true
    },
    
    // 创建文件
    createFile() {
      if (!this.newFileForm.name) {
        this.$message.warning('文件名不能为空')
        return
      }
      
      if (this.useMockData) {
        setTimeout(() => {
          // 添加到当前文件列表
          this.files.push({
            name: this.newFileForm.name,
            type: 'file',
            size: this.newFileForm.content.length,
            mtime: new Date(),
            permissions: '-rw-r--r--'
          })
          
          // 添加文件内容
          const filePath = this.currentPath === '/' 
            ? `/${this.newFileForm.name}` 
            : `${this.currentPath}/${this.newFileForm.name}`
          mockFileContents[filePath] = this.newFileForm.content
          
          this.$message.success('文件创建成功')
          this.newFileDialogVisible = false
        }, 500)
      } else {
        this.$http.post('/file/create', {
          path: this.currentPath,
          name: this.newFileForm.name,
          content: this.newFileForm.content
        })
          .then(() => {
            this.$message.success('文件创建成功')
            this.newFileDialogVisible = false
            this.fetchFiles()
          })
          .catch(error => {
            this.$message.error(error.response?.data?.error || '创建文件失败')
          })
      }
    },
    
    // 编辑文件
    handleEdit(file) {
      if (!this.isEditable(file)) {
        this.$message.warning('该文件不支持在线编辑')
        return
      }
      
      this.fileContentLoading = true
      this.editFileDialogVisible = true
      this.currentEditFile = file
      
      if (this.useMockData) {
        setTimeout(() => {
          const filePath = this.currentPath === '/' 
            ? `/${file.name}` 
            : `${this.currentPath}/${file.name}`
          this.editFileContent = mockFileContents[filePath] || ''
          this.fileContentLoading = false
        }, 500)
      } else {
        this.$http.get('/file/read', {
          params: {
            path: this.currentPath === '/' ? `/${file.name}` : `${this.currentPath}/${file.name}`
          }
        })
          .then(res => {
            this.editFileContent = res.data.content
            this.fileContentLoading = false
          })
          .catch(error => {
            this.$message.error(error.response?.data?.error || '读取文件失败')
            this.editFileDialogVisible = false
            this.fileContentLoading = false
          })
      }
    },
    
    // 保存文件
    saveFile() {
      if (!this.isAdmin) {
        this.$message.warning('需要管理员权限进行此操作')
        return
      }
      
      if (this.useMockData) {
        setTimeout(() => {
          const filePath = this.currentPath === '/' 
            ? `/${this.currentEditFile.name}` 
            : `${this.currentPath}/${this.currentEditFile.name}`
          mockFileContents[filePath] = this.editFileContent
          
          // 更新文件大小
          const fileIndex = this.files.findIndex(f => f.name === this.currentEditFile.name)
          if (fileIndex !== -1) {
            this.files[fileIndex].size = this.editFileContent.length
            this.files[fileIndex].mtime = new Date()
          }
          
          this.$message.success('文件保存成功')
          this.editFileDialogVisible = false
        }, 500)
      } else {
        this.$http.post('/file/write', {
          path: this.currentPath === '/' ? `/${this.currentEditFile.name}` : `${this.currentPath}/${this.currentEditFile.name}`,
          content: this.editFileContent
        })
          .then(() => {
            this.$message.success('文件保存成功')
            this.editFileDialogVisible = false
            this.fetchFiles()
          })
          .catch(error => {
            this.$message.error(error.response?.data?.error || '保存文件失败')
          })
      }
    },
    
    // 重命名文件或文件夹
    handleRename(item) {
      if (!this.isAdmin) {
        this.$message.warning('需要管理员权限进行此操作')
        return
      }
      
      this.currentRenameItem = item
      this.renameForm.newName = item.name
      this.renameDialogVisible = true
    },
    
    // 执行重命名
    renameItem() {
      if (!this.renameForm.newName) {
        this.$message.warning('名称不能为空')
        return
      }
      
      if (this.useMockData) {
        setTimeout(() => {
          const index = this.files.findIndex(f => f.name === this.currentRenameItem.name)
          if (index !== -1) {
            this.files[index].name = this.renameForm.newName
            this.files[index].mtime = new Date()
          }
          
          this.$message.success('重命名成功')
          this.renameDialogVisible = false
        }, 500)
      } else {
        this.$http.post('/file/rename', {
          path: this.currentPath,
          oldName: this.currentRenameItem.name,
          newName: this.renameForm.newName
        })
          .then(() => {
            this.$message.success('重命名成功')
            this.renameDialogVisible = false
            this.fetchFiles()
          })
          .catch(error => {
            this.$message.error(error.response?.data?.error || '重命名失败')
          })
      }
    },
    
    // 删除文件或文件夹
    handleDelete(item) {
      if (!this.isAdmin) {
        this.$message.warning('需要管理员权限进行此操作')
        return
      }
      
      this.$confirm(`确定要删除 ${item.name} 吗?${item.type === 'directory' ? ' 该操作将删除目录下的所有文件!' : ''}`, '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        if (this.useMockData) {
          setTimeout(() => {
            const index = this.files.findIndex(f => f.name === item.name)
            if (index !== -1) {
              this.files.splice(index, 1)
            }
            
            this.$message.success('删除成功')
          }, 500)
        } else {
          this.$http.post('/file/delete', {
            path: this.currentPath === '/' ? `/${item.name}` : `${this.currentPath}/${item.name}`,
            isDirectory: item.type === 'directory'
          })
            .then(() => {
              this.$message.success('删除成功')
              this.fetchFiles()
            })
            .catch(error => {
              this.$message.error(error.response?.data?.error || '删除失败')
            })
        }
      }).catch(() => {})
    },
    
    // 获取文件图标
    getFileIcon(file) {
      if (file.type === 'directory') {
        return 'el-icon-folder'
      }
      
      // 根据文件扩展名返回相应图标
      const ext = file.name.split('.').pop().toLowerCase()
      
      if (['html', 'htm', 'xml'].includes(ext)) return 'el-icon-document'
      if (['js', 'ts', 'json'].includes(ext)) return 'el-icon-document'
      if (['css', 'scss', 'less'].includes(ext)) return 'el-icon-document'
      if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg'].includes(ext)) return 'el-icon-picture'
      if (['mp3', 'wav', 'ogg'].includes(ext)) return 'el-icon-headset'
      if (['mp4', 'avi', 'mkv', 'flv'].includes(ext)) return 'el-icon-video-camera'
      if (['pdf'].includes(ext)) return 'el-icon-document'
      if (['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'].includes(ext)) return 'el-icon-document'
      if (['zip', 'rar', 'tar', 'gz', '7z'].includes(ext)) return 'el-icon-document'
      
      return 'el-icon-document'
    },
    
    // 格式化文件大小
    formatSize(row) {
      if (row.type === 'directory') return '-'
      
      const size = row.size
      if (size < 1024) return size + ' B'
      if (size < 1024 * 1024) return (size / 1024).toFixed(2) + ' KB'
      if (size < 1024 * 1024 * 1024) return (size / (1024 * 1024)).toFixed(2) + ' MB'
      return (size / (1024 * 1024 * 1024)).toFixed(2) + ' GB'
    },
    
    // 格式化日期
    formatDate(row) {
      const date = new Date(row.mtime)
      return date.toLocaleString()
    },
    
    // 获取路径段截至指定索引
    getPathUpTo(index) {
      return '/' + this.pathSegments.slice(0, index + 1).join('/')
    },
    
    // 判断文件是否可编辑
    isEditable(file) {
      if (file.type !== 'file') return false
      
      // 支持编辑的文件类型（扩展名）
      const editableExtensions = [
        'txt', 'log', 'md', 'json', 'xml', 'html', 'htm', 'css', 'js', 'ts',
        'py', 'php', 'rb', 'sh', 'bash', 'conf', 'ini', 'yaml', 'yml', 'env'
      ]
      
      const ext = file.name.split('.').pop().toLowerCase()
      return editableExtensions.includes(ext) || !ext
    }
  }
}
</script>

<style scoped>
.file-path {
  margin-bottom: 15px;
  padding: 10px;
  background-color: #f5f7fa;
  border-radius: 4px;
}

.file-toolbar {
  margin-bottom: 15px;
  display: flex;
  justify-content: space-between;
}

.file-name {
  cursor: pointer;
  color: #409EFF;
  text-decoration: none;
}

.file-name:hover {
  text-decoration: underline;
}
</style> 